# -*- coding: utf-8 -*-
from django.http import QueryDict
from django.template.defaultfilters import slugify

from .. import settings

import widgets

class Field(object):
    """
    Base field that can be added to a *Sorter*.
    Example usage::
    
        sorters.Field(label="article name", callback=sorters.from_fields("name")),
            
    Field value is normally generated slugifying the passed label, but can be
    manually set passing *value="my-value"* to the field constructor.
    
    Sorter fields provide some **useful api**:
        - *field.label*: the label of the field that can be displayed
        - *field.value*: the value present in the querydict
        - *field.is_selected*: True if you are sorting by this field
        - *field.url*: the url of the page that actually sort the queryset
        - *field.callback(objects)*: order the passed queryset by this field
    """
    def __init__(self, label, value=None, callback=None, is_default=False, 
        desc=False, widget=None):
        self.label = label
        self.value = slugify(self.label) if value is None else value
        self._callback = callback
        self.is_selected = self.is_default = is_default
        self.desc = desc
        
        if widget is None:
            self.widget = widgets.Link()
        elif callable(widget):
            self.widget = widget()
        else:
            self.widget = widget
        
        self._direction = settings.ASC
        self.is_reversed = False
        self.querydict = None
        self.name = None
        
    def __unicode__(self):
        """
        Renders the field widget.
        """
        return self.widget.render(self.is_selected, self.is_reversed, 
            self.is_default, label=self.label, name=self.name, 
            value=self.value, direction=self.direction)
        
    def callback(self, queryset):
        """
        Fire the callback that manipulate the passed queryset.
        This is called from *FilterForm.run()* method.
        """
        if callable(self._callback):
            return self._callback(self, queryset)
        return self._callback
        
    def set_querydict(self, querydict):
        """
        Set the querydict in the field and in the associated widget.
        """
        # field and widget querydict must always be a *django.http.QueryDict*
        # instance
        if not querydict:
            querydict = QueryDict("")
        self.querydict = self.widget.querydict = querydict
        
    @property
    def direction(self):
        """
        Returns the actual order direction (settings.ASC or settings.DESC).
        """
        # do not touch this code
        not_reversed = self.desc ^ self.is_reversed ^ self.is_selected
        return settings.ASC if not_reversed else settings.DESC
        
    @property
    def url(self):
        """
        Return the url for the sorting link.
        It is only used to expose a widget method to frontend developer.
        """
        return self.widget.get_url(self.is_selected, self.is_reversed, 
            self.is_default, self.name, self.value)
